package com.cuntian.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cuntian.contant.Constants;
import com.cuntian.dto.LoginDTO;
import com.cuntian.dto.ModifyPwdDTO;
import com.cuntian.dto.RegisterDTO;
import com.cuntian.entity.User;
import com.cuntian.enums.ResultCode;
import com.cuntian.exception.GlobalException;
import com.cuntian.mapper.UserMapper;
import com.cuntian.model.IMSessionInfo;
import com.cuntian.service.IUserService;
import com.cuntian.util.BeanUtils;
import com.cuntian.vo.LoginVO;
import com.cuntian.vo.UserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Override
    public LoginVO login(LoginDTO dto) {
        User user = this.priFindUserByPhone(dto.getPhone());
        if (Objects.isNull(user)) {
            throw new GlobalException("用户不存在");
        }
        if(!SaSecureUtil.sha256(dto.getPassword()).equals(user.getPassword())){
            throw new GlobalException(ResultCode.PASSWOR_ERROR);
        }
        // sa-token设置用户登入并保存用户信息
        StpUtil.login(user.getUid());
        IMSessionInfo imSessionInfo = new IMSessionInfo();
        imSessionInfo.setUserId(user.getUid());
        imSessionInfo.setTerminal(dto.getTerminal());
        StpUtil.getSession().set(Constants.USER_SESSION,imSessionInfo);
        LoginVO vo = BeanUtils.copyProperties(user, LoginVO.class);
        vo.setChatToken(StpUtil.getTokenValue());
        return vo;
    }

    @Override
    public List<UserVO>  findUserByUserName(String username) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(User::getUserName, username).last("limit 20");
        queryWrapper.eq(User::getUserName, username);
        List<User> users = this.list(queryWrapper);
        return users.stream().map(u->{
            UserVO userVO = BeanUtils.copyProperties(u, UserVO.class);
            return userVO;
        }).collect(Collectors.toList());
    }


    @Override
    public void update(UserVO vo) {
        IMSessionInfo session = (IMSessionInfo) StpUtil.getSession().get(Constants.USER_SESSION);
        if (!session.getUserId().equals(vo.getUid())) {
            throw new GlobalException("不允许修改其他用户的信息!");
        }
        User user = this.getById(vo.getUid());
        if (Objects.isNull(user)) {
            throw new GlobalException("用户不存在");
        }
        if(!user.getPhone().equals(vo.getPhone()) && !Objects.isNull(findUserByPhone(vo.getPhone()))){
            throw new GlobalException("改电话已被其他人绑定");
        }
        if(!vo.getTheme().equals(Constants.THEME_LIGHT) && !vo.getTheme().equals(Constants.THEME_DARK)){
            throw new GlobalException("主题不存在");
        }

        // 修改用户的头像和用户名
        if (!user.getUserName().equals(vo.getUserName())
                || !user.getHeadImage().equals(vo.getHeadImage())) {
            LambdaUpdateWrapper<User> updateWrapper=Wrappers.lambdaUpdate();
            updateWrapper.eq(User::getUid,session.getUserId());
            updateWrapper.set(User::getUserName,vo.getUserName());
            updateWrapper.set(User::getHeadImage,vo.getHeadImage());
            updateWrapper.set(User::getPhone,vo.getPhone());
            updateWrapper.set(User::getTheme,vo.getTheme());
            this.update(updateWrapper);
        }
    }

    @Override
    public UserVO findUserById(Long id) {
        User user = this.getById(id);
        UserVO vo = BeanUtils.copyProperties(user, UserVO.class);
        return vo;
    }

    @Override
    public UserVO findUserByPhone(String phone) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(User::getPhone,phone);
        User user = this.getOne(queryWrapper);
        UserVO vo = BeanUtils.copyProperties(user, UserVO.class);
        return vo;
    }

    @Override
    public void logOut() {
        StpUtil.logout();
    }

    private User priFindUserByPhone(String phone) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(User::getPhone,phone);
        User user = this.getOne(queryWrapper);
        return user;
    }

    @Override
    public void register(RegisterDTO dto) {
        User user = this.priFindUserByPhone(dto.getPhone());
        if (!Objects.isNull(user)) {
            throw new GlobalException(ResultCode.PHONE_ALREADY_REGISTER);
        }
        user = BeanUtils.copyProperties(dto, User.class);
        user.setPassword(SaSecureUtil.sha256(user.getPassword()));
        this.save(user);
    }

    @Override
    public void modifyPassword(ModifyPwdDTO dto) {
        IMSessionInfo session = (IMSessionInfo) StpUtil.getSession().get(Constants.USER_SESSION);
        User user = this.getById(session.getUserId());
        if (!SaSecureUtil.sha256(user.getPassword()).equals(dto.getOldPassword())) {
            throw new GlobalException("旧密码不正确");
        }
        user.setPassword(SaSecureUtil.sha256(dto.getNewPassword()));
        this.updateById(user);
    }
}
